package com.woniu.postbar.service.impl;

import com.woniu.common.constant.PostBarConstant;
import com.woniu.common.constant.RedisKeyConstant;
import com.woniu.common.utils.LocalDateTimeConvertUtil;
import com.woniu.postbar.entity.dto.PostLikeCountDTO;
import com.woniu.postbar.entity.dto.PostLikeDTO;
import com.woniu.postbar.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

@Service
@Slf4j
public class RedisServiceImpl implements RedisService {

    /**
     * 封装的redis hash不存在点赞信息
     */
    @Autowired
    private HashOperations<String,String,Object> redisHash;


    @Override
    public Integer getLikeStatus(Integer postId, Integer userId) {
        //判断redis中的点赞状态
        if (redisHash.hasKey(RedisKeyConstant.USER_POST_LIKE, postId + PostBarConstant.COLON + userId)){
            HashMap<String, Object> map = (HashMap<String, Object>) redisHash.get(RedisKeyConstant.USER_POST_LIKE,postId + PostBarConstant.COLON + userId);
            return (Integer) map.get(PostBarConstant.POST_STATUS);
        }
        return PostBarConstant.LIKE_STATUS_NO_EXIT;
    }

    @Override
    public void saveLikedRedis(Integer postId, Integer userId) {
        // 生成key
        String key = String.valueOf(postId + userId);
        // 封装value 喜欢状态 更新时间
        HashMap<String,Object> map = new HashMap<>();
        map.put(PostBarConstant.POST_STATUS, PostBarConstant.LIKE_STATUS_LIKE);
        map.put(PostBarConstant.POST_LIKE_TIME, System.currentTimeMillis());
        redisHash.put(RedisKeyConstant.USER_POST_LIKE, key, map);
    }

    @Override
    public void unlikeFromRedis(Integer postId, Integer userId) {
        // 生成key
        String key = String.valueOf(postId + userId);
        // 封装value 喜欢状态 更新时间
        HashMap<String,Object> map = new HashMap<>();
        map.put(PostBarConstant.POST_STATUS, PostBarConstant.LIKE_STATUS_UNLIKE);
        map.put(PostBarConstant.POST_LIKE_TIME, System.currentTimeMillis());
        redisHash.put(RedisKeyConstant.USER_POST_LIKE, key, map);
    }

    @Override
    public void deleteLikedFromRedis(Integer postId, Integer userId) {
        // 生成key
        String key = String.valueOf(postId + userId);
        //删除redis
        redisHash.delete(RedisKeyConstant.USER_POST_LIKE, key);
    }

    @Override
    public void decrementLikedCount(Integer postId, Integer delta) {
        //hsah在key中的指定字段加上增量
        redisHash.increment(RedisKeyConstant.USER_POST_LIKE_COUNT, String.valueOf(postId), delta);
    }

    @Override
    public List<PostLikeDTO> getLikedDataFromRedis(){
        //匹配key获取全部键值对
        Cursor<Map.Entry<String, Object>> cursor = redisHash.scan(RedisKeyConstant.USER_POST_LIKE, ScanOptions.NONE);
        List<PostLikeDTO> list = new ArrayList<>();
        while (cursor.hasNext()) {
            Map.Entry<String, Object> entry = cursor.next();
            String key = entry.getKey();
            //分离postId，userId, 解析value
            String[] split = key.split(PostBarConstant.COLON);
            String postId = split[0];
            String userId = split[1];
            HashMap<String, Object> map = (HashMap<String, Object>)entry.getValue();
            Integer status = (Integer) map.get(PostBarConstant.POST_STATUS);
            Long updateTimeStamp = (long) map.get(PostBarConstant.POST_LIKE_TIME);
            LocalDateTime updateTime = LocalDateTimeConvertUtil.getDateTimeOfTimestamp(updateTimeStamp);// 时间戳转为LocalDateTime
            //组装成 UserLike 对象
            PostLikeDTO userLikesDTO = new PostLikeDTO(postId, userId, status, updateTime);
            list.add(userLikesDTO);
            //存到 list 后从 Redis 中清理缓存
            redisHash.delete(RedisKeyConstant.USER_POST_LIKE, key);
        }
        return list;
    }

    @Override
    public List<PostLikeCountDTO> getLikedCountFromRedis() {
        // 匹配key获取全部键值对
        Cursor<Map.Entry<String, Object>> cursor = redisHash.scan(RedisKeyConstant.USER_POST_LIKE_COUNT, ScanOptions.NONE);
        List<PostLikeCountDTO> list = new ArrayList<>();
        while (cursor.hasNext()){
            Map.Entry<String, Object> map = cursor.next();
            //点赞数量存储
            String key = map.getKey();
            PostLikeCountDTO dto = new PostLikeCountDTO(key, (Integer)map.getValue());
            list.add(dto);
            //从Redis中删除这条记录
            redisHash.delete(RedisKeyConstant.USER_POST_LIKE_COUNT, key);
        }
        return list;
    }
}
